Atklājiet GraphQL federācijas jaudu, izmantojot shēmu savienošanu. Uzziniet, kā izveidot vienotu GraphQL API no vairākiem servisiem, uzlabojot mērogojamību un uzturēšanu.
GraphQL federācija: Shēmu savienošana (Schema Stitching) - Visaptverošs ceļvedis
Pastāvīgi mainīgajā moderno lietojumprogrammu izstrādes ainavā nepieciešamība pēc mērogojamas un uzturamas arhitektūras ir kļuvusi par galveno prioritāti. Mikroservisi ar tiem raksturīgo modularitāti un neatkarīgo izvietojamību ir kļuvuši par populāru risinājumu. Tomēr daudzu mikropakalpojumu pārvaldība var radīt sarežģījumus, jo īpaši, ja runa ir par vienotas API nodrošināšanu klienta lietojumprogrammām. Šeit savu lomu spēlē GraphQL federācija un īpaši shēmu savienošana (Schema Stitching).
Kas ir GraphQL federācija?
GraphQL federācija ir jaudīga arhitektūra, kas ļauj jums izveidot vienotu GraphQL API no vairākiem pamatā esošiem GraphQL servisiem (kas bieži pārstāv mikroservisus). Tā ļauj izstrādātājiem vaicāt datus no dažādiem servisiem tā, it kā tie būtu viens grafs, vienkāršojot klienta pieredzi un samazinot nepieciešamību pēc sarežģītas orķestrēšanas loģikas klienta pusē.
GraphQL federācijai ir divas galvenās pieejas:
- Shēmu savienošana (Schema Stitching): Tā ietver vairāku GraphQL shēmu apvienošanu vienā, vienotā shēmā vārtejas slānī. Tā ir agrīnāka pieeja un balstās uz bibliotēkām, lai pārvaldītu shēmu apvienošanu un vaicājumu deleģēšanu.
- Apollo federācija: Tā ir jaunāka un robustāka pieeja, kas izmanto deklaratīvu shēmas valodu un īpašu vaicājumu plānotāju, lai pārvaldītu federācijas procesu. Tā piedāvā papildu funkcijas, piemēram, tipu paplašinājumus, atslēgu direktīvas un izkliedēto trasēšanu.
Šis raksts ir veltīts shēmu savienošanai, pētot tās koncepcijas, priekšrocības, ierobežojumus un praktisko ieviešanu.
Izpratne par shēmu savienošanu
Shēmu savienošana ir vairāku GraphQL shēmu apvienošanas process vienā, saskaņotā shēmā. Šī vienotā shēma darbojas kā fasāde, slēpjot no klienta pamatā esošo servisu sarežģītību. Kad klients veic pieprasījumu uz savienoto shēmu, vārteja gudri novirza pieprasījumu uz attiecīgo(-ajiem) pamatā esošo(-ajiem) servisu(-iem), iegūst datus un apvieno rezultātus, pirms tos atgriež klientam.
Iedomājieties to šādi: jums ir vairāki restorāni (servisi), kas katrs specializējas dažādās virtuvēs. Shēmu savienošana ir kā universāla ēdienkarte, kas apvieno visus ēdienus no katra restorāna. Kad klients (klients) pasūta no universālās ēdienkartes, pasūtījums tiek gudri novirzīts uz attiecīgajām restorānu virtuvēm, ēdiens tiek pagatavots un pēc tam apvienots vienā piegādē klientam.
Shēmu savienošanas pamatjēdzieni
- Attālinātās shēmas: Tās ir katra pamatā esošā servisa individuālās GraphQL shēmas. Katrs serviss nodrošina savu shēmu, kas definē tā sniegtos datus un operācijas.
- Vārteja: Vārteja ir centrālais komponents, kas atbild par attālināto shēmu savienošanu un vienotās shēmas nodrošināšanu klientam. Tā saņem klienta pieprasījumus, novirza tos uz attiecīgajiem servisiem un apvieno rezultātus.
- Shēmu apvienošana: Tas ir attālināto shēmu apvienošanas process vienā shēmā. Tas bieži ietver tipu un lauku pārdēvēšanu, lai izvairītos no konfliktiem, un attiecību definēšanu starp tipiem dažādās shēmās.
- Vaicājumu deleģēšana: Kad klients veic pieprasījumu uz savienoto shēmu, vārtejai ir jādeleģē pieprasījums uz attiecīgo(-ajiem) pamatā esošo(-ajiem) servisu(-iem), lai iegūtu datus. Tas ietver klienta vaicājuma pārtulkošanu vaicājumā, ko var saprast attālinātais serviss.
- Rezultātu apkopošana: Pēc tam, kad vārteja ir ieguvusi datus no pamatā esošajiem servisiem, tai ir jāapvieno rezultāti vienā atbildē, ko var atgriezt klientam. Tas bieži ietver datu pārveidošanu, lai tie atbilstu savienotās shēmas struktūrai.
Shēmu savienošanas priekšrocības
Shēmu savienošana piedāvā vairākas pārliecinošas priekšrocības organizācijām, kas pieņem mikroservisu arhitektūru:
- Vienota API: Nodrošina vienotu, konsekventu API klientiem, vienkāršojot datu piekļuvi un samazinot nepieciešamību klientiem tieši mijiedarboties ar vairākiem servisiem. Tā rezultātā izstrādātāja pieredze ir tīrāka un intuitīvāka.
- Samazināta klienta sarežģītība: Klientiem ir nepieciešams mijiedarboties tikai ar vienoto shēmu, pasargājot tos no pamatā esošās mikroservisu arhitektūras sarežģītības. Tas vienkāršo klienta puses izstrādi un samazina nepieciešamo koda apjomu klientā.
- Palielināta mērogojamība: Ļauj neatkarīgi mērogot atsevišķus servisus, pamatojoties uz to īpašajām vajadzībām. Tas uzlabo sistēmas kopējo mērogojamību un noturību. Piemēram, lietotāju servisu, kas piedzīvo lielu slodzi, var mērogot, neietekmējot citus servisus, piemēram, produktu katalogu.
- Uzlabota uzturēšana: Veicina modularitāti un atbildības sadalīšanu, atvieglojot atsevišķu servisu uzturēšanu un attīstību. Izmaiņas vienā servisā, visticamāk, neietekmēs citus servisus.
- Pakāpeniska ieviešana: Var ieviest pakāpeniski, ļaujot jums pakāpeniski pāriet no monolītas arhitektūras uz mikroservisu arhitektūru. Jūs varat sākt, savienojot esošās API, un pēc tam pakāpeniski sadalīt monolītu mazākos servisos.
Shēmu savienošanas ierobežojumi
Lai gan shēmu savienošana piedāvā daudzas priekšrocības, ir svarīgi apzināties tās ierobežojumus:
- Sarežģītība: Shēmu savienošanas ieviešana un pārvaldība var būt sarežģīta, īpaši lielās un sarežģītās sistēmās. Rūpīga plānošana un dizains ir būtiski.
- Veiktspējas virsizdevumi: Vārteja rada zināmus veiktspējas virsizdevumus papildu netiešā slāņa un nepieciešamības deleģēt vaicājumus un apkopot rezultātus dēļ. Rūpīga optimizācija ir ļoti svarīga, lai samazinātu šos virsizdevumus.
- Shēmu konflikti: Apvienojot shēmas no dažādiem servisiem, var rasties konflikti, īpaši, ja tie izmanto tos pašus tipu nosaukumus vai lauku nosaukumus. Tas prasa rūpīgu shēmas dizainu un, iespējams, tipu un lauku pārdēvēšanu.
- Ierobežotas papildu funkcijas: Salīdzinot ar Apollo federāciju, shēmu savienošanai trūkst dažas papildu funkcijas, piemēram, tipu paplašinājumi un atslēgu direktīvas, kas var apgrūtināt attiecību pārvaldību starp tipiem dažādās shēmās.
- Rīku briedums: Rīki un ekosistēma ap shēmu savienošanu nav tik nobriedusi kā Apollo federācijas gadījumā. Tas var apgrūtināt problēmu atkļūdošanu un novēršanu.
Shēmu savienošanas praktiskā ieviešana
Apskatīsim vienkāršotu piemēru, kā ieviest shēmu savienošanu, izmantojot Node.js un graphql-tools
bibliotēku (populāra izvēle shēmu savienošanai). Šis piemērs ietver divus mikroservisus: Lietotāju servisu un Produktu servisu.
1. Definējiet attālinātās shēmas
Vispirms definējiet GraphQL shēmas katram no attālinātajiem servisiem.
Lietotāju serviss (user-service.js
):
const { buildSchema } = require('graphql');
const userSchema = buildSchema(`
type User {
id: ID!
name: String
email: String
}
type Query {
user(id: ID!): User
}
`);
const users = [
{ id: '1', name: 'Alice Smith', email: 'alice@example.com' },
{ id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];
const userRoot = {
user: (args) => users.find(user => user.id === args.id),
};
module.exports = {
schema: userSchema,
rootValue: userRoot,
};
Produktu serviss (product-service.js
):
const { buildSchema } = require('graphql');
const productSchema = buildSchema(`
type Product {
id: ID!
name: String
price: Float
userId: ID! # Ārējā atslēga uz Lietotāju servisu
}
type Query {
product(id: ID!): Product
}
`);
const products = [
{ id: '101', name: 'Laptop', price: 1200, userId: '1' },
{ id: '102', name: 'Smartphone', price: 800, userId: '2' },
];
const productRoot = {
product: (args) => products.find(product => product.id === args.id),
};
module.exports = {
schema: productSchema,
rootValue: productRoot,
};
2. Izveidojiet vārtejas servisu
Tagad izveidojiet vārtejas servisu, kas savienos abas shēmas kopā.
Vārtejas serviss (gateway.js
):
const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');
async function createRemoteSchema(uri) {
const fetcher = async (params) => {
const response = await fetch(uri, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});
return response.json();
};
const schema = await introspectSchema(fetcher);
return makeRemoteExecutableSchema({
schema,
fetcher,
});
}
async function main() {
const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
const productSchema = await createRemoteSchema('http://localhost:4002/graphql');
const stitchedSchema = stitchSchemas({
subschemas: [
{ schema: userSchema },
{ schema: productSchema },
],
typeDefs: `
extend type Product {
user: User
}
`,
resolvers: {
Product: {
user: {
selectionSet: `{ userId }`,
resolve(product, args, context, info) {
return info.mergeInfo.delegateToSchema({
schema: userSchema,
operation: 'query',
fieldName: 'user',
args: {
id: product.userId,
},
context,
info,
});
},
},
},
},
});
const app = express();
app.use('/graphql', graphqlHTTP({
schema: stitchedSchema,
graphiql: true,
}));
app.listen(4000, () => console.log('Vārtejas serveris darbojas http://localhost:4000/graphql'));
}
main().catch(console.error);
3. Palaidiet servisus
Jums būs jāpalaiž Lietotāju serviss un Produktu serviss dažādos portos. Piemēram:
Lietotāju serviss (ports 4001):
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: rootValue,
graphiql: true,
}));
app.listen(4001, () => console.log('Lietotāju serviss darbojas http://localhost:4001/graphql'));
Produktu serviss (ports 4002):
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: rootValue,
graphiql: true,
}));
app.listen(4002, () => console.log('Produktu serviss darbojas http://localhost:4002/graphql'));
4. Vaicājiet savienoto shēmu
Tagad jūs varat vaicāt savienoto shēmu caur vārteju (kas darbojas 4000. portā). Jūs varat izpildīt šādu vaicājumu:
query {
product(id: "101") {
id
name
price
user {
id
name
email
}
}
}
Šis vaicājums iegūst produktu ar ID "101" un arī saņem saistīto lietotāju no Lietotāju servisa, demonstrējot, kā shēmu savienošana ļauj jums vaicāt datus no vairākiem servisiem vienā pieprasījumā.
Papildu shēmu savienošanas metodes
Papildus pamata piemēram, šeit ir dažas papildu metodes, kuras var izmantot, lai uzlabotu jūsu shēmu savienošanas ieviešanu:
- Shēmas deleģēšana: Tas ļauj deleģēt vaicājuma daļas dažādiem servisiem, pamatojoties uz pieprasītajiem datiem. Piemēram, jūs varētu deleģēt `User` tipa izšķiršanu Lietotāju servisam un `Product` tipa izšķiršanu Produktu servisam.
- Shēmas transformācija: Tā ietver attālinātā servisa shēmas modificēšanu, pirms tā tiek savienota vienotā shēmā. Tas var būt noderīgi, lai pārdēvētu tipus un laukus, pievienotu jaunus laukus vai noņemtu esošos laukus.
- Pielāgoti atrisinātāji (resolvers): Jūs varat definēt pielāgotus atrisinātājus vārtejā, lai apstrādātu sarežģītas datu transformācijas vai iegūtu datus no vairākiem servisiem un apvienotu tos vienā rezultātā.
- Konteksta koplietošana: Bieži vien ir nepieciešams koplietot konteksta informāciju starp vārteju un attālinātajiem servisiem, piemēram, autentifikācijas marķierus vai lietotāju ID. To var panākt, nododot konteksta informāciju kā daļu no vaicājuma deleģēšanas procesa.
- Kļūdu apstrāde: Ieviesiet robustu kļūdu apstrādi, lai eleganti apstrādātu kļūdas, kas rodas attālinātajos servisos. Tas var ietvert kļūdu reģistrēšanu, lietotājam draudzīgu kļūdu ziņojumu atgriešanu vai neveiksmīgu pieprasījumu atkārtošanu.
Izvēle starp shēmu savienošanu un Apollo federāciju
Lai gan shēmu savienošana ir dzīvotspējīgs variants GraphQL federācijai, Apollo federācija ir kļuvusi par populārāku izvēli, pateicoties tās papildu funkcijām un uzlabotajai izstrādātāju pieredzei. Šeit ir abu pieeju salīdzinājums:
Funkcija | Shēmu savienošana | Apollo federācija |
---|---|---|
Shēmas definīcija | Izmanto esošo GraphQL shēmas valodu | Izmanto deklaratīvu shēmas valodu ar direktīvām |
Vaicājumu plānošana | Nepieciešama manuāla vaicājumu deleģēšana | Automātiska vaicājumu plānošana ar Apollo vārteju |
Tipu paplašinājumi | Ierobežots atbalsts | Iebūvēts atbalsts tipu paplašinājumiem |
Atslēgu direktīvas | Netiek atbalstīts | Izmanto @key direktīvu, lai identificētu entītijas |
Izkliedētā trasēšana | Nepieciešama manuāla ieviešana | Iebūvēts atbalsts izkliedētai trasēšanai |
Rīki un ekosistēma | Mazāk nobrieduši rīki | Nobriedušāki rīki un liela kopiena |
Sarežģītība | Var būt sarežģīti pārvaldīt lielās sistēmās | Paredzēta lielām un sarežģītām sistēmām |
Kad izvēlēties shēmu savienošanu:
- Jums jau ir esoši GraphQL servisi un vēlaties tos ātri apvienot.
- Jums ir nepieciešams vienkāršs federācijas risinājums un nav nepieciešamas papildu funkcijas.
- Jums ir ierobežoti resursi un vēlaties izvairīties no Apollo federācijas iestatīšanas virsizdevumiem.
Kad izvēlēties Apollo federāciju:
- Jūs veidojat lielu un sarežģītu sistēmu ar vairākām komandām un servisiem.
- Jums ir nepieciešamas papildu funkcijas, piemēram, tipu paplašinājumi, atslēgu direktīvas un izkliedētā trasēšana.
- Jūs vēlaties robustāku un mērogojamāku federācijas risinājumu.
- Jūs dodat priekšroku deklaratīvākai un automatizētākai federācijas pieejai.
Reālās pasaules piemēri un lietošanas gadījumi
Šeit ir daži reālās pasaules piemēri, kā var izmantot GraphQL federāciju, ieskaitot shēmu savienošanu:
- E-komercijas platforma: E-komercijas platforma varētu izmantot GraphQL federāciju, lai apvienotu datus no vairākiem servisiem, piemēram, produktu kataloga servisa, lietotāju servisa, pasūtījumu servisa un maksājumu servisa. Tas ļauj klientiem viegli iegūt visu informāciju, kas nepieciešama, lai parādītu produktu detaļas, lietotāju profilus, pasūtījumu vēsturi un maksājumu informāciju.
- Sociālo mediju platforma: Sociālo mediju platforma varētu izmantot GraphQL federāciju, lai apvienotu datus no servisiem, kas pārvalda lietotāju profilus, ierakstus, komentārus un "patīk" atzīmes. Tas ļauj klientiem efektīvi iegūt visu informāciju, kas nepieciešama, lai parādītu lietotāja profilu, viņa ierakstus un ar šiem ierakstiem saistītos komentārus un "patīk" atzīmes.
- Finanšu pakalpojumu lietojumprogramma: Finanšu pakalpojumu lietojumprogramma varētu izmantot GraphQL federāciju, lai apvienotu datus no servisiem, kas pārvalda kontus, transakcijas un investīcijas. Tas ļauj klientiem viegli iegūt visu informāciju, kas nepieciešama, lai parādītu kontu atlikumus, transakciju vēsturi un investīciju portfeļus.
- Satura pārvaldības sistēma (CMS): CMS var izmantot GraphQL federāciju, lai integrētu datus no dažādiem avotiem, piemēram, rakstiem, attēliem, video un lietotāju radīta satura. Tas nodrošina vienotu API, lai iegūtu visu saturu, kas saistīts ar konkrētu tēmu vai autoru.
- Veselības aprūpes lietojumprogramma: Integrējiet pacientu datus no dažādām sistēmām, piemēram, elektroniskajiem veselības ierakstiem (EVI), laboratorijas rezultātiem un pierakstu plānošanas. Tas piedāvā ārstiem vienotu piekļuves punktu visaptverošai pacientu informācijai.
Labākās prakses shēmu savienošanai
Lai nodrošinātu veiksmīgu shēmu savienošanas ieviešanu, ievērojiet šīs labākās prakses:
- Rūpīgi plānojiet savu shēmu: Pirms sākat savienot shēmas kopā, rūpīgi izplānojiet vienotās shēmas struktūru. Tas ietver attiecību definēšanu starp tipiem dažādās shēmās, tipu un lauku pārdēvēšanu, lai izvairītos no konfliktiem, un kopējo datu piekļuves modeļu apsvēršanu.
- Izmantojiet konsekventus nosaukumu piešķiršanas noteikumus: Pieņemiet konsekventus nosaukumu piešķiršanas noteikumus tipiem, laukiem un operācijām visos servisos. Tas palīdzēs izvairīties no konfliktiem un atvieglos vienotās shēmas izpratni.
- Dokumentējiet savu shēmu: Rūpīgi dokumentējiet vienoto shēmu, iekļaujot tipu, lauku un operāciju aprakstus. Tas atvieglos izstrādātājiem shēmas izpratni un lietošanu.
- Pārraugiet veiktspēju: Pārraugiet vārtejas un attālināto servisu veiktspēju, lai identificētu un novērstu jebkādus veiktspējas sastrēgumus. Izmantojiet rīkus, piemēram, izkliedēto trasēšanu, lai izsekotu pieprasījumus vairākos servisos.
- Ieviesiet drošību: Ieviesiet atbilstošus drošības pasākumus, lai aizsargātu vārteju un attālinātos servisus no neatļautas piekļuves. Tas var ietvert autentifikācijas un autorizācijas mehānismu izmantošanu, kā arī ievades validāciju un izvades kodēšanu.
- Versējiet savu shēmu: Attīstot shēmas, versējiet tās atbilstoši, lai nodrošinātu, ka klienti var turpināt lietot vecākas shēmas versijas bez traucējumiem. Tas palīdzēs izvairīties no kritisko izmaiņu ieviešanas un nodrošinās atpakaļsaderību.
- Automatizējiet izvietošanu: Automatizējiet vārtejas un attālināto servisu izvietošanu, lai nodrošinātu, ka izmaiņas var ātri un uzticami izvietot. Tas palīdzēs samazināt kļūdu risku un uzlabos sistēmas kopējo veiklību.
Noslēgums
GraphQL federācija ar shēmu savienošanu piedāvā jaudīgu pieeju, lai veidotu vienotas API no vairākiem servisiem mikroservisu arhitektūrā. Izprotot tās pamatjēdzienus, priekšrocības, ierobežojumus un ieviešanas metodes, jūs varat izmantot shēmu savienošanu, lai vienkāršotu datu piekļuvi, uzlabotu mērogojamību un veicinātu uzturēšanu. Lai gan Apollo federācija ir kļuvusi par modernāku risinājumu, shēmu savienošana joprojām ir dzīvotspējīgs variants vienkāršākiem scenārijiem vai integrējot esošus GraphQL servisus. Rūpīgi apsveriet savas īpašās vajadzības un prasības, lai izvēlētos labāko pieeju jūsu organizācijai.